//using System.Collections.Generic;
//using System.Diagnostics;
//using System.IO;
//using UnityEditor;
//using UnityEngine;
//using UnityEngine.Rendering;
//
//namespace Gameplay.PVE
//{
//    public class PveSceneEditor : EditorWindow
//    {
//        public class ObjTransform
//        {
//
//        }
//        private class ObjSource
//        {
//            public ObjSource()
//            {
//                    
//            }
//
//            public int layer;
//            public MeshFilter filter;
//            public MeshRenderer render;
//            public int vertexCount;
//            public int trianglesCount;
//            public string matName;
//            public string objName;
//            public int totalVertices;
//            public int totalTriangles;
//            public string status;
//            public Color statusColor;
//            public Vector3 position;
//            public Vector3 angle;
//            public Vector3 scale;
//            public int part;
//
//        }
//        private static SSceneConfig m_settings;
//        private static string m_settingsPath = "Assets/Arts/Scene/RPG/Data/sceneSettings.asset";
//
//        private Vector2 m_materialScrollPos;
//        private Vector2 m_nodeScrollPos;
//        private Vector2 m_logScrollPos;
//        private static int m_drawcallCount;
//        private static int m_allTotalVertices = 0;
//        private static int m_allTotalTringles = 0;
//        private static List<string> m_logString = new List<string>();
//        private int m_selectedViewId;
//        private int m_selectedId = 0;
//        private int m_selectedObjIndex = -1;
//        private static string m_activeSceneName;
//        private static Dictionary<System.Type, Dictionary<string, int>> m_exportedStrList = new Dictionary<System.Type, Dictionary<string, int>>();
//        private int m_selectedType = 0;//0:autobatched  1：gpuinstancing   2：other
//        private static SceneSettings m_sceneSettings;
//        private static Dictionary<Material, Dictionary<int, List<ObjSource>>> m_batchedGameObjectDict = new Dictionary<Material, Dictionary<int, List<ObjSource>>>();
//        private static Dictionary<Material, Dictionary<int, List<ObjSource>>> m_gpuinstancingGameObjectDic = new Dictionary<Material, Dictionary<int, List<ObjSource>>>();
//        private static Dictionary<Material, List<ObjSource>> m_otherGameObjectDic = new Dictionary<Material, List<ObjSource>>();
//
//        private static Dictionary<Material,Dictionary<int,Material>> newGameObjectMatDic = new Dictionary<Material, Dictionary<int,Material>>();
//
//        private static List<Texture> lightMaps = new List<Texture>();
//        private static List<string> lightMapPaths = new List<string>();
//
//        private static List<Vector3> partOffsetList = new List<Vector3>();
//
//        private static string prefabRootPath;
//        private static string matRootPath;
//        private static string skyBoxMatPath;
//        private static string texturePath;
//        private static string meshPath;
//
//        private static void ClearCache()
//        {
//            m_logString.Clear();
//            m_batchedGameObjectDict.Clear();
//            m_gpuinstancingGameObjectDic.Clear();
//            m_otherGameObjectDic.Clear();
//            lightMaps.Clear();
//            lightMapPaths.Clear();
//            partOffsetList.Clear();
//            newGameObjectMatDic.Clear();
//        }
//
//        public static bool GenerateAll(string mapConfigName = "")
//        {
//            Stopwatch sw = Stopwatch.StartNew();
//            sw.Start();
//            var name = string.IsNullOrEmpty(mapConfigName) ? UnityEngine.SceneManagement.SceneManager.GetActiveScene().name : mapConfigName;
//            Initialize(name);
//            string sceneRoot = m_sceneSettings.resourcesParent + m_sceneSettings.prefabFolder + name;
//            string prefabFullFolder = Application.dataPath.Replace("Assets", "") + sceneRoot;
//            DeleteDir(prefabFullFolder, true);
//            Directory.CreateDirectory(prefabFullFolder);
//
//            string artRoot = m_sceneSettings.artsParent + name;
//
//            prefabRootPath = sceneRoot + "/Prefabs";
//            matRootPath = artRoot + "/Materials";
//            texturePath = sceneRoot + "/Textures";
//            meshPath = artRoot + "/Meshes";
//            skyBoxMatPath = sceneRoot + "/Materials";
//            DeleteDir(Application.dataPath.Replace("Assets", "") + prefabRootPath, true);
//            Directory.CreateDirectory(Application.dataPath.Replace("Assets", "") + prefabRootPath);
//            DeleteDir(Application.dataPath.Replace("Assets", "") + matRootPath, true);
//            Directory.CreateDirectory(Application.dataPath.Replace("Assets", "") + matRootPath);
//            DeleteDir(Application.dataPath.Replace("Assets", "") + texturePath, true);
//            Directory.CreateDirectory(Application.dataPath.Replace("Assets", "") + texturePath);
//            DeleteDir(Application.dataPath.Replace("Assets", "") + meshPath, true);
//            Directory.CreateDirectory(Application.dataPath.Replace("Assets", "") + meshPath);
//            DeleteDir(Application.dataPath.Replace("Assets", "") + skyBoxMatPath, true);
//            Directory.CreateDirectory(Application.dataPath.Replace("Assets", "") + skyBoxMatPath);
//            CopyLightMaps();
//            var root = GameObject.Find("[Root]");
//            if (root == null)
//            {
//                EditorUtility.DisplayDialog("错误", "没有找到场景的根节点，请保证场景中有命名为 [Root] 的根节点，Active状态为True", "关闭");
//                return false;
//            }
//
//            partOffsetList.Clear();
//            for (int i = 0; i < root.transform.childCount; i++)
//            {
//                var transform = root.transform.GetChild(i);
//                partOffsetList.Add(transform.position);
//                transform.position = Vector3.zero;
//            }
//
//            CalculateSH9();
//            ProcessRoot(root.transform);
//            
//           // try
//           // { 
//            //    AssetDatabase.Refresh();
//              //  AssetDatabase.StartAssetEditing();
//                Generate(root.transform,name);
//           // }
//           // finally
//           // {
//              //  AssetDatabase.StopAssetEditing();
//          //  } 
//            
//            
//            // for (int i = 0; i < root.transform.childCount; i++)
//            // {
//            //     var transform = root.transform.GetChild(i);
//            //     transform.position = partOffsetList[i];
//            // }
//            //
//            var endTime = System.DateTime.Now.Millisecond;
//            sw.Stop();
//            Debug.LogFormat("总耗时 {0} s", sw.ElapsedMilliseconds/1000);
//            ClearCache();
//
//            return true;
//        }
//
//        static int[] _idSHA = {
//            Shader.PropertyToID("m_unity_SHAr"),
//            Shader.PropertyToID("m_unity_SHAg"),
//            Shader.PropertyToID("m_unity_SHAb")
//        };
//
//        static int[] _idSHB = {
//            Shader.PropertyToID("m_unity_SHBr"),
//            Shader.PropertyToID("m_unity_SHBg"),
//            Shader.PropertyToID("m_unity_SHBb")
//        };
//
//        static int _idSHC =
//            Shader.PropertyToID("m_unity_SHC");
//        
//        
//        private static SphericalHarmonicsL2 sh;
//        public static void CalculateSH9()
//        {
//            LightProbes.GetInterpolatedProbe(Vector3.zero, null, out sh);
//        }
//
//        private static void AddSH9(Material material)
//        {
//            for (var i = 0; i < 3; i++)
//            {
//                var sha = new Vector4(sh[i, 3], sh[i, 1], sh[i, 2], sh[i, 0] - sh[i, 6]);
//                material.SetVector(_idSHA[i], sha);
//            }
//                
//            // Quadratic polynomials
//            for (var i = 0; i < 3; i++)
//            {
//                var shb = new Vector4(
//                    sh[i, 4], sh[i, 6], sh[i, 5] * 3, sh[i, 7]
//                );
//                material.SetVector(_idSHB[i],shb);
//            }
//               
//
//            // Final quadratic polynomial
//            var shc = new Vector4(
//                sh[0, 8], sh[2, 8], sh[1, 8], 1
//            );
//            material.SetVector(_idSHC, shc);
//        }
//        
//        private static void CopyLightMaps()
//        {
//            var name = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
//            lightMaps.Clear();
//            lightMapPaths.Clear();
//            var lightMapPathRoot = texturePath;
//            for (int i = 0; i < LightmapSettings.lightmaps.Length; i++)
//            {
//                string st = lightMapPathRoot + string.Format("/Lightmap-{0}_comp_light.exr",i);
//                var path = AssetDatabase.GetAssetPath(LightmapSettings.lightmaps[i].lightmapColor);
//                AssetDatabase.CopyAsset(path, st);
//
//                /*TextureImporter textureImporter = TextureImporter.GetAtPath(st) as TextureImporter;
//                if (!textureImporter.isReadable)
//                {
//                    textureImporter.isReadable = true;
//                    textureImporter.SaveAndReimport();
//                    AssetDatabase.Refresh();
//                }*/
//                var texture = AssetDatabase.LoadAssetAtPath<Texture>(st);
//                /*TextureImporter textureImporter = TextureImporter.GetAtPath(st) as TextureImporter;
//                if (textureImporter.mipmapEnabled)
//                {
//                    textureImporter.mipmapEnabled = false;
//                    textureImporter.SaveAndReimport();
//                    AssetDatabase.Refresh();
//                }*/
//                lightMaps.Add(texture);
//                lightMapPaths.Add(st);
//            }
//
//            m_settings.ambientColor = RenderSettings.ambientLight;
//            m_settings.reflectionMode = RenderSettings.defaultReflectionMode;
//            var skyBoxMatPath = PveSceneEditor.skyBoxMatPath + "/SkyBoxMat.mat";
//            var skyBoxMat = Material.Instantiate(RenderSettings.skybox);
//            AssetDatabase.CreateAsset(skyBoxMat, skyBoxMatPath);
//            AssetDatabase.Refresh();
//            m_settings.skyBoxMaterialPath = skyBoxMatPath;
//            var lightMapPAth = AssetDatabase.GetAssetPath(Lightmapping.lightingDataAsset);
//            var reflectProbePath = lightMapPAth.Replace("LightingData.asset", "ReflectionProbe-0.exr");
//            var reflectProbeNewPath = texturePath + "/ReflectionProbe-0.exr";
//            AssetDatabase.CopyAsset(reflectProbePath, reflectProbeNewPath);
//            AssetDatabase.Refresh();
//            m_settings.reflectionProbePath = reflectProbeNewPath;
//            m_settings.ambientMode = RenderSettings.ambientMode;
//        }
//
//        private static void Initialize(string name)
//        {
//            m_activeSceneName = name;
//            if (m_sceneSettings == null)
//            {
//                m_sceneSettings = AssetDatabase.LoadAssetAtPath(m_settingsPath, typeof(ScriptableObject)) as SceneSettings;
//            }
//            string path = string.Format("Assets/ResourcesAssets/Pve/Scene/{0}.asset",m_activeSceneName);
//            m_settings = AssetDatabase.LoadAssetAtPath<ScriptableObject>(path) as SSceneConfig;
//            if (m_settings == null)
//            {
//                m_settings = ScriptableObject.CreateInstance<SSceneConfig>();
//                AssetDatabase.CreateAsset(m_settings, path);
//            }
//            multiMaterialPrefabs.Clear();
//            prefabs.Clear();
//            newGameObjectMatDic.Clear();
//        }
//        private static void CheckMaterial()
//        {
//            //InitConfig();
//            LogToString("Start To CheckMaterial");
//            var root = GameObject.Find("[Root]");
//            if (root == null)
//            {
//                UnityEngine.Debug.Log("Root 不能为null:  ");
//                return;
//            }
//            CheckMaterial(root);
//            var effectRoot = GameObject.Find("[Effect]");
//            if (effectRoot != null)
//            {
//                CheckMaterial(effectRoot);
//            }
//            LogToString("End To CheckMaterial");
//        }
//
//        private static Material GetMat(MeshRenderer mr)
//        {
//            if (newGameObjectMatDic.TryGetValue(mr.sharedMaterial, out var dic) &&
//                dic.TryGetValue(mr.lightmapIndex, out var m))
//            {
//                return m;
//            }
//            Debug.LogError("找不到mat " + mr);
//            return null;
//        }
//        
//        private static Material GetMat(Material mat,int lightmapIndex)
//        {
//            if (newGameObjectMatDic.TryGetValue(mat, out var dic) &&
//                dic.TryGetValue(lightmapIndex, out var m))
//            {
//                return m;
//            }
//            Debug.LogError("找不到mat " + mat);
//            return null;
//        }
//
//        private static Material GetMat(MeshRenderer mr,Shader shader)
//        {
//            bool needAdd = true;
//            var m = mr.sharedMaterial;
//            Material realMat = null;
//            if (!newGameObjectMatDic.TryGetValue(m, out var dic))
//            {
//                newGameObjectMatDic.Add(m,new Dictionary<int,Material>());
//                needAdd = true;
//            }
//            else if (dic.TryGetValue(mr.lightmapIndex,out var mat))
//            {
//                needAdd = false;
//                realMat = mat;
//            }
//
//            if (needAdd)
//            {
//                Material cloneMat = UnityEngine.Object.Instantiate(m);
//                var matName = "mat_" + m.name + "_" + mr.lightmapIndex;
//                matName = matName.Replace('#', 'j');
//                matName = matName.Replace(' ', '0');
//                matName = matName.Replace('-', '_');
//                cloneMat.name = matName;
//                cloneMat.shader = shader;
//                cloneMat.renderQueue = m.renderQueue;
//                cloneMat.enableInstancing = false;
//                if (mr.lightmapIndex >= 0 && mr.lightmapIndex < lightMaps.Count)
//                {
//                    cloneMat.SetTexture("_LightMap",lightMaps[mr.lightmapIndex]);
//                    cloneMat.DisableKeyword("_ATTEN");
//                    cloneMat.SetFloat("_ATTEN",0);
//                }
//                realMat = cloneMat;
//                if (realMat.shader.name.Contains("CityGround"))
//                {
//                    AddSH9(realMat);
//                }
//                newGameObjectMatDic[m].Add(mr.lightmapIndex,realMat);
//            }
//            return realMat;
//        }
//
//        private static Material GetMultiMat(MeshRenderer mr,Shader shader,Material m)
//        {
//            bool needAdd = true;
//            Material realMat = null;
//            if (!newGameObjectMatDic.TryGetValue(m, out var dic))
//            {
//                newGameObjectMatDic.Add(m,new Dictionary<int,Material>());
//                needAdd = true;
//            }
//            else if (dic.TryGetValue(mr.lightmapIndex,out var mat))
//            {
//                needAdd = false;
//                realMat = mat;
//            }
//
//            if (needAdd)
//            {
//                Material cloneMat = UnityEngine.Object.Instantiate(m);
//                var matName = "mat_" + m.name + "_" + mr.lightmapIndex;
//                matName = matName.Replace('#', 'j');
//                matName = matName.Replace(' ', '0');
//                matName = matName.Replace('-', '_');
//                cloneMat.name = matName;
//                cloneMat.shader = shader;
//                cloneMat.renderQueue = m.renderQueue;
//                cloneMat.enableInstancing = false;
//                if (mr.lightmapIndex >= 0 && mr.lightmapIndex < lightMaps.Count)
//                {
//                    cloneMat.SetTexture("_LightMap",lightMaps[mr.lightmapIndex]);
//                    cloneMat.DisableKeyword("_ATTEN");
//                    cloneMat.SetFloat("_ATTEN",0);
//                }
//                realMat = cloneMat;
//                if (realMat.shader.name.Contains("CityGround"))
//                {
//                    AddSH9(realMat);
//                }
//                newGameObjectMatDic[m].Add(mr.lightmapIndex,realMat);
//            }
//            return realMat;
//        }
//        
//        private static void ProcessRoot(Transform root)
//        {
//            Asynclize(root);
//            m_drawcallCount = 0;
//            m_allTotalVertices = 0;
//            m_allTotalTringles = 0;
//            foreach (var item in m_batchedGameObjectDict)
//            {
//                int tC = 0;
//                int vC = 0;
//                foreach (var it in item.Value)
//                {
//                    for (int i = 0; i < it.Value.Count; i++)
//                    {
//                        vC += it.Value[i].vertexCount;
//                        tC += it.Value[i].trianglesCount;
//                    }
//                }
//                foreach (var it in item.Value)
//                {
//                    for (int i = 0; i < it.Value.Count; i++)
//                    {
//                        it.Value[i].totalVertices = vC;
//                        it.Value[i].totalTriangles = tC;
//                    }
//                }
//                m_drawcallCount++;
//                m_allTotalVertices += vC;
//                m_allTotalTringles += tC;
//            }
//            foreach (var item in m_gpuinstancingGameObjectDic)
//            {
//                foreach (var it in item.Value)
//                {
//                    int tC = 0;
//                    int vC = 0;
//                    for (int i = 0; i < it.Value.Count; i++)
//                    {
//                        vC += it.Value[i].vertexCount;
//                    }
//                    m_drawcallCount++;
//                    tC = it.Value[0].trianglesCount;
//                    for (int i = 0; i < it.Value.Count; i++)
//                    {
//                        it.Value[i].totalVertices = vC;
//                        it.Value[i].totalTriangles = tC;
//                    }
//                    m_allTotalVertices += vC;
//                    m_allTotalTringles += tC;
//                }
//            }
//            foreach (var item in m_otherGameObjectDic)
//            {
//                int tC = 0;
//                int vC = 0;
//                for (int i = 0; i < item.Value.Count; i++)
//                {
//                    vC += item.Value[i].vertexCount;
//                    tC += item.Value[i].trianglesCount;
//                }
//                for (int i = 0; i < item.Value.Count; i++)
//                {
//                    item.Value[i].totalTriangles = tC;
//                    item.Value[i].totalVertices = vC;
//                }
//                m_drawcallCount++;
//                m_allTotalVertices += vC;
//                m_allTotalTringles += tC;
//            }
//        }
//
//        private static void Generate(Transform root,string name)
//        {
//            m_logString.Clear();
//            //CheckMaterial();
//            var artLightMapFolder = UnityEngine.SceneManagement.SceneManager.GetActiveScene().path.Replace(".unity", "");
//            LogToString("Start To Generate" + name);
//            m_settings.objs = new List<SSceneConfig.SceneObj>();
//            m_settings.prefabFolder = m_sceneSettings.prefabFolder + name;
//            string prefabFullFolder = Application.dataPath.Replace("Assets", "") + m_sceneSettings.resourcesParent + m_sceneSettings.prefabFolder + name;
//            /*DeleteDir(prefabFullFolder, true);
//            Directory.CreateDirectory(prefabFullFolder);*/
//
//            foreach (var item in newGameObjectMatDic.Values)
//            {
//                foreach (var item2 in item.Values)
//                {
//                    var matName = item2.name;
//                    string matFullPath = matRootPath + "/" + matName + ".mat";
//                    AssetDatabase.CreateAsset(item2, matFullPath);
//                    
//                }
//            }
//            // AssetDatabase.Refresh();
//            foreach (KeyValuePair<Material, Dictionary<int, List<ObjSource>>> entry in m_batchedGameObjectDict)
//            {
//                var mat = entry.Key;
//                var goList = entry.Value;
//
//                if (goList.Count > 0)
//                {
//                    Dictionary<int,List<ObjSource>> list = new Dictionary<int,List<ObjSource>>();
//                    foreach (var item in goList)
//                    {
//                        for (int i = 0; i < item.Value.Count; i++)
//                        {
//                            int partIndex = item.Value[i].part;
//                            if (!list.ContainsKey(partIndex))
//                            {
//                                list.Add(partIndex,new List<ObjSource>());
//                            }
//                            list[partIndex].Add(item.Value[i]);
//                        }
//                    }
//                    foreach (var item in list)
//                    {
//                        ExportBatchNode(root.transform, item.Value, mat,item.Key);
//                    }
//
//                }
//            }
//            List<Texture> lightMapTextures = lightMaps;
//            List<string> lightMapPath = lightMapPaths;
//            foreach (var item in m_gpuinstancingGameObjectDic)
//            {
//                var mat = item.Key;
//                foreach (var it in item.Value)
//                {
//                    var mf = it.Value[0].filter;
//                    var mr = it.Value[0].render;
//                    int index = m_sceneSettings.toGpuInstancingShaderNames.IndexOf(mat.shader.name);
//                    Mesh mesh = mf.sharedMesh;
//                    int meshInst = mesh.GetInstanceID();
//                    if (mesh == null)
//                    {
//                        UnityEngine.Debug.LogError("find mesh is null ：" + mf.name);
//                        LogToString("find mesh is null ：" + mf.name);
//                        continue;
//                    }
//                    var exportMeshName = "inst_msh_" + GetSourceName(mesh);
//                    var exportMatName = "inst_mat_" + GetSourceName(mat);
//                    string meshPath = PveSceneEditor.meshPath + "/" + exportMeshName + ".asset";
//                    var cloneMesh = UnityEngine.Object.Instantiate(mesh);
//                    cloneMesh.name = exportMeshName;
//                    AssetDatabase.CreateAsset(cloneMesh, meshPath);
//                    string matPath = m_sceneSettings.resourcesParent + m_settings.prefabFolder + "/" + exportMatName + ".mat";
//                    Material cloneMat = UnityEngine.Object.Instantiate(mat);
//                    cloneMat.name = exportMatName;
//                    int lightMapIndex = -1;
//                    for (int i = 0; i < it.Value.Count; i++)
//                    {
//                        var obj = new SSceneConfig.SceneObj();
//                        var mrs = it.Value[i].render;
//                        var mrsName = exportMeshName;
//                        obj.name = mrsName;
//                        lightMapIndex = mrs.lightmapIndex;
//                        obj.lightmapIndex = mrs.lightmapIndex;
//                        obj.lightmapScaleOffset = mrs.lightmapScaleOffset;
//                        if (mat.HasProperty("_Quality"))
//                        {
//                            obj.quality = mat.GetInt("_Quality");
//                        }
//                        if (index == 0)
//                        {
//                            obj.gpuInstanceState = 1;
//                            obj.wave = mat.GetFloat("_Speed") * mat.GetFloat("_Amplitude");
//                            obj.cutoff = mat.GetFloat("_Cutout");
//                            Vector3 windDir = mat.GetVector("_dir");
//                            obj.windX = windDir.x;
//                            obj.windY = windDir.y;
//                            obj.windZ = windDir.z;
//                        }
//                        else if (index == 1)
//                        {
//                            obj.gpuInstanceState = 2;
//                        }
//
//                        Matrix4x4 localToWorldMatrix = mrs.transform.localToWorldMatrix;
//                        obj.m00 = localToWorldMatrix.m00;
//                        obj.m01 = localToWorldMatrix.m01;
//                        obj.m02 = localToWorldMatrix.m02;
//                        obj.m03 = localToWorldMatrix.m03;
//                        obj.m10 = localToWorldMatrix.m10;
//                        obj.m11 = localToWorldMatrix.m11;
//                        obj.m12 = localToWorldMatrix.m12;
//                        obj.m13 = localToWorldMatrix.m13;
//                        obj.m20 = localToWorldMatrix.m20;
//                        obj.m21 = localToWorldMatrix.m21;
//                        obj.m22 = localToWorldMatrix.m22;
//                        obj.m23 = localToWorldMatrix.m23;
//                        obj.m30 = localToWorldMatrix.m30;
//                        obj.m31 = localToWorldMatrix.m31;
//                        obj.m32 = localToWorldMatrix.m32;
//                        obj.m33 = localToWorldMatrix.m33;
//                        obj.layer = mrs.gameObject.layer;
//
//                        obj.meshName = exportMeshName;
//                        obj.matName = exportMatName;
//                        obj.part = it.Value[i].part;
//                        obj.partOffset = partOffsetList[obj.part];
//                        m_settings.objs.Add(obj);
//                    }
//
//                    if (lightMapIndex != -1)
//                    {
//                        if (index == 0)
//                        {
//                            cloneMat.shader = Shader.Find(m_sceneSettings.targetGpuInstancingShaderNames[index]);
//                            cloneMat.SetColor("_Color", mat.GetColor("_Color"));
//                            cloneMat.SetFloat("_Cutout", mat.GetFloat("_Cutout"));
//                            cloneMat.SetFloat("_Speed", mat.GetFloat("_Speed"));
//                            cloneMat.SetFloat("_Amplitude", mat.GetFloat("_Amplitude"));
//                            cloneMat.SetVector("_dir", mat.GetVector("_dir"));
//                            // cloneMat.SetTexture("_LtMap", lightMapTextures[lightMapIndex] as Texture2D);
//                        }
//                        else if (index == 1)
//                        {
//                            cloneMat.shader = Shader.Find(m_sceneSettings.targetGpuInstancingShaderNames[index]);
//                            // cloneMat.SetTexture("_LtMap", lightMapTextures[lightMapIndex] as Texture2D);
//                        }
//                    }
//
//                    cloneMat.enableInstancing = true;
//                    cloneMat.renderQueue = mat.renderQueue;
//                    AssetDatabase.CreateAsset(cloneMat, matPath);
//                }
//            }
//
//            var outPutPrefabs = new Dictionary<PrefabInstance,string>();
//            /*foreach (var item in prefabs.Values)
//            {
//                foreach (var item2 in item.Values)
//                {
//                    outPutPrefabs.Add(item2,string.Empty);
//                }
//            }*/
//            foreach (var item in m_otherGameObjectDic)
//            {
//                for (int i = 0; i < item.Value.Count; i++)
//                {
//                    var mf = item.Value[i].filter;
//                    var mr = item.Value[i].render;
//                    int meshInstanceId = mf.sharedMesh.GetInstanceID();
//                    int matInstanceId = item.Key.GetInstanceID();
//                    var exportMrName = "prf_otr_" + GetSourceName(mr.gameObject);
//                    var prefab = prefabs[meshInstanceId][matInstanceId];
//
//                    GameObject o = null;
//                    if (outPutPrefabs.TryGetValue(prefab,out var path))
//                    {
//                        exportMrName = path;
//                    }
//                    else
//                    {
//                        o = GetNewGameObject(exportMrName,item.Value[i],item.Key,false);//GameObject.Instantiate(mr.gameObject);
//                        outPutPrefabs[prefab] = exportMrName;
//                    }
//                    
//                    var obj = new SSceneConfig.SceneObj();
//                    obj.name = exportMrName;
//                    obj.lightmapIndex = mr.lightmapIndex;
//                    obj.lightmapScaleOffset = mr.lightmapScaleOffset;
//
//                    obj.gpuInstanceState = 0;
//                
//                    obj.rotation =  item.Value[i].angle;
//
//                    obj.scale = item.Value[i].scale;
//
//                    obj.position = item.Value[i].position;
//                    
//                    obj.part = item.Value[i].part;
//                    obj.partOffset = partOffsetList[obj.part];
//                    
//
//                    Vector3 min = item.Value[i].render.bounds.min;
//                    Vector3 max = item.Value[i].render.bounds.max;
//                    Vector3 size = max - min;
//                    Bounds bounds = new Bounds(min + size/2, size);
//                    if (size.x <= 0)
//                        size.x = 0.2f;
//                    if (size.y <= 0)
//                        size.y = 0.2f;
//                    if (size.z <= 0)
//                        size.z = 0.2f;
//                    bounds.size = size;
//                    
//                    obj.bound = bounds;
//                    m_settings.objs.Add(obj);
//                    string objStr = prefabRootPath + "/" + exportMrName + ".prefab";
//                    obj.path = objStr;
//                 
//                    if (o != null)
//                    {
//                        // var mmrr = o.GetComponentsInChildren<MeshRenderer>();
//                        // for (int j = 0; j < mmrr.Length; j++)
//                        // {
//                        //     mmrr[j].lightmapIndex = mr.lightmapIndex;
//                        //     mmrr[j].lightmapScaleOffset = mr.lightmapScaleOffset;
//                        // }
//
//                        // var lma = o.AddComponent<LightMapApply>();
//                        // lma.lightmapIndex = mr.lightmapIndex;
//                        // lma.lightmapScaleOffset = mr.lightmapScaleOffset;
//                        o.isStatic = false;
//                        // UnityEngine.Object tempPrefab = PrefabUtility.CreateEmptyPrefab(objStr);
//                        // PrefabUtility.ReplacePrefab(o, tempPrefab);
//                        PrefabUtility.SaveAsPrefabAsset(o, objStr);
//                        GameObject.DestroyImmediate(o);
//                    }
//                }
//            }
//
//            foreach (var item in multiMaterialPrefabs)
//            {
//                var mr = item.gameObject.GetComponent<MeshRenderer>();
//                var exportMrName = "prf_otr_multi_mat_" + GetSourceName(mr.gameObject);
//                exportMrName = exportMrName.Replace('(', 'c');
//                exportMrName = exportMrName.Replace(')', 'e');
//                var prefab = item.gameObject;
//
//                GameObject o = null;
//                /*if (outPutPrefabs.TryGetValue(prefab,out var path))
//                {
//                    exportMrName = path;
//                }
//                else*/
//                {
//                    Vector3 scale = prefab.transform.lossyScale;
//                    Vector3 localScale = prefab.transform.localScale;
//                    Vector3 angle = prefab.transform.eulerAngles;
//                    Vector3 position = prefab.transform.position;
//                    // prefab.transform.position = Vector3.zero;
//                    // prefab.transform.eulerAngles = Vector3.zero;
//                    // prefab.transform.localScale = scale;
//                    //o = GetNewGameObjectMultiMaterial(exportMrName,prefab,item.part);//GameObject.Instantiate(mr.gameObject);
//                    o = GameObject.Instantiate(mr.gameObject);
//                    //outPutPrefabs[prefab] = exportMrName;
//                    // prefab.transform.position = position;
//                    // prefab.transform.eulerAngles = angle;
//                    // prefab.transform.localScale = localScale;
//                }
//
//                //if (mf.sharedMesh.uv2 != null && mf.sharedMesh.uv2.Length > 0)
//                //{
//                //    for (int j = 0; j < mf.sharedMesh.uv2.Length; j++)
//                //    {
//                //        Vector3 vt_ = mf.sharedMesh.uv2[j];
//                //        vt_.x = mr.lightmapScaleOffset.x * vt_.x + mr.lightmapScaleOffset.z;
//                //        vt_.y = mr.lightmapScaleOffset.y * vt_.y + mr.lightmapScaleOffset.w;
//                //        mf.sharedMesh.uv2[j] = vt_;
//                //    }
//                //}
//                // Vector3 originScale = Vector3.one;//prefab.sourceObj.transform.lossyScale;
//                // Vector3 originAngle = Vector3.zero;//prefab.sourceObj.transform.eulerAngles;
//                // Vector3 originPosition = Vector3.zero;//prefab.sourceObj.transform.position;
//                var obj = new SSceneConfig.SceneObj();
//                obj.name = exportMrName;
//                obj.lightmapIndex = mr.lightmapIndex;
//                obj.lightmapScaleOffset = mr.lightmapScaleOffset;
//                
//                obj.gpuInstanceState = 0;
//                obj.rotation = prefab.transform.eulerAngles;
//                
//                obj.scale = prefab.transform.lossyScale;
//                
//                obj.position = prefab.transform.position;
//                
//                obj.part = item.part;
//                obj.partOffset = partOffsetList[obj.part];
//                Vector3 min = mr.bounds.min;
//                Vector3 max = mr.bounds.max;
//                Vector3 size = max - min;
//                Bounds bounds = new Bounds(min + size/2, size);
//                if (size.x <= 0)
//                    size.x = 0.2f;
//                if (size.y <= 0)
//                    size.y = 0.2f;
//                if (size.z <= 0)
//                    size.z = 0.2f;
//                bounds.size = size;
//                    
//                obj.bound = bounds;
//                m_settings.objs.Add(obj);
//                string objStr = prefabRootPath + "/" + exportMrName + ".prefab";
//                obj.path = objStr;
//                /*if (o != null)
//                {
//                    o.isStatic = false;
//                    UnityEngine.Object tempPrefab = PrefabUtility.CreateEmptyPrefab(objStr);
//                    PrefabUtility.ReplacePrefab(o, tempPrefab);
//                    GameObject.DestroyImmediate(o);
//                }*/
//                if (o != null)
//                {
//                    // var mmrr = o.GetComponentsInChildren<MeshRenderer>();
//                    // for (int j = 0; j < mmrr.Length; j++)
//                    // {
//                    //     mmrr[j].lightmapIndex = mr.lightmapIndex;
//                    //     mmrr[j].lightmapScaleOffset = mr.lightmapScaleOffset;
//                    // }
//                    // var lma = o.AddComponent<LightMapApply>();
//                    // lma.lightmapIndex = mr.lightmapIndex;
//                    // lma.lightmapScaleOffset = mr.lightmapScaleOffset;
//                    o.isStatic = false;
//                    // UnityEngine.Object tempPrefab = PrefabUtility.CreateEmptyPrefab(objStr);
//                    // PrefabUtility.ReplacePrefab(o, tempPrefab);
//                    PrefabUtility.SaveAsPrefabAsset(o, objStr);
//                    GameObject.DestroyImmediate(o);
//                }
//            }
//            
//            /*m_settings.postProcessPath = prefabRootPath + "/prf_postProcessCamera.prefab";
//            var skyBoxPath =  prefabRootPath +
//                              "/prf_skyBox.prefab";
//            if (skyBoxObj == null)
//            {
//                m_settings.skyBoxPath = "";
//            }
//            else
//            {
//                m_settings.skyBoxPath = skyBoxPath;
//                UnityEngine.Object tempPrefab = PrefabUtility.CreateEmptyPrefab( skyBoxPath);
//                var skyBox = GameObject.Instantiate(skyBoxObj);
//                PrefabUtility.ReplacePrefab(skyBox, tempPrefab);
//                GameObject.DestroyImmediate(skyBox);
//            }*/
//
//            //var camera = Camera.main;
//            //if (camera != null)
//            if (m_settings.objs.Count > 0)
//            {
//                m_settings.lightMapColorPath = new List<string>();
//                m_settings.lightMapColorPath.AddRange(lightMapPath);
//                m_settings.fogColor = RenderSettings.fogColor;
//                m_settings.isFog = RenderSettings.fog;
//                m_settings.fogStart = RenderSettings.fogStartDistance;
//                m_settings.fogEnd = RenderSettings.fogEndDistance;
//                m_settings.fogMode = RenderSettings.fogMode;
//
//                /*if (File.Exists(m_settings.lightMapColorPath))
//                {
//                    AssetDatabase.DeleteAsset(m_settings.lightMapColorPath);
//                }
//                AssetDatabase.CreateAsset(lightMapTexture, m_settings.lightMapColorPath);
//                AssetDatabase.SaveAssets();
//                AssetDatabase.Refresh();*/
//
//                EditorUtility.SetDirty(m_settings);
//                AssetDatabase.SaveAssets();
//                AssetDatabase.Refresh();
//                
//                /*string st = m_sceneSettings.resourcesParent + m_sceneSettings.prefabFolder + name + "/Lightmap-0_comp_light.exr";
//                string old = AssetDatabase.GetAssetPath(LightmapSettings.lightmaps[0].lightmapColor);
//                AssetDatabase.CopyAsset(old, st);*/
//                LogToString("Success Generate:" + name);
//                ClearCache();
//            }
//        }
//
//        private static void PasteComponent(GameObject targetObject,Component newComponent)
//        {
//            UnityEditorInternal.ComponentUtility.CopyComponent(newComponent);
//            Component oldComponent = targetObject.GetComponent (newComponent.GetType ());
//            if (oldComponent != null) {
//                if (UnityEditorInternal.ComponentUtility.PasteComponentValues (oldComponent)) {
//                    Debug.Log ("Paste Values " + newComponent.GetType ().ToString () + " Success");
//                } else {
//                    Debug.Log ("Paste Values " + newComponent.GetType ().ToString () + " Failed");
//                }
//            } else {
//                if (UnityEditorInternal.ComponentUtility.PasteComponentAsNew (targetObject)) {
//                    Debug.Log ("Paste New Values " + newComponent.GetType ().ToString () + " Success");
//                } else {
//                    Debug.Log ("Paste New Values " + newComponent.GetType ().ToString () + " Failed");
//                }
//            }
//        }
//        private static GameObject GetNewGameObject(string name,ObjSource sample,Material m,bool isBatch)
//        {
//            if (isBatch)
//            {
//                return GetNewGameObject(name, sample, m);
//            }
//
//            MeshFilter mf = sample.filter;
//            Mesh msh = mf.sharedMesh;
//
//            Vector3 tempPosition = sample.filter.transform.position;
//            Vector3 tempEulerAngles = sample.filter.transform.eulerAngles;
//            sample.filter.transform.position = Vector3.zero;
//            sample.filter.transform.eulerAngles = Vector3.zero;
//
//            Vector3 lossyScale = sample.filter.transform.lossyScale;
//            Vector3 localScale = sample.filter.transform.localScale;
//            
//            MeshRenderer mr = sample.render;
//
//
//            
//            
//            ////write to disk
//            string prefabFullFolder = m_sceneSettings.resourcesParent + m_settings.prefabFolder;
//
//            var sourceName = GetSourceName(m);
//            string assetName = "mesh_ort_" + sourceName;
//            string prefabName = name;
//            string assetFullPath = meshPath + "/" + assetName + ".asset";
//            
//
//            sample.filter.transform.position = tempPosition;
//            sample.filter.transform.eulerAngles = tempEulerAngles;
//            sample.filter.transform.localScale = localScale;
//
//            // string originPath = AssetDatabase.GetAssetPath(mf.sharedMesh);
//            // AssetDatabase.CreateAsset(mf.sharedMesh,assetFullPath);
//            // AssetDatabase.CopyAsset(originPath, assetFullPath);
//
//            Mesh mesh = mf.sharedMesh;
//            mesh.name = assetName;
//            Material sharedMat = GetMat(mr);
//
//            GameObject batchGameObject = new GameObject(prefabName);
//
//            MeshFilter _mf = batchGameObject.AddComponent<MeshFilter>();
//            _mf.sharedMesh = mesh;//AssetDatabase.LoadAssetAtPath<Mesh>(assetFullPath);
//
//            MeshRenderer _mr = batchGameObject.AddComponent<MeshRenderer>();
//            //Debug.LogError(prefabName + " " + sharedMat);
//            _mr.sharedMaterial = sharedMat;//AssetDatabase.LoadAssetAtPath<Material>(matFullPath);
//            batchGameObject.layer = sample.layer;
//            /*string prefabFullPath = prefabFullFolder + "/" + prefabName + ".prefab";
//            UnityEngine.Object tempPrefab = PrefabUtility.CreateEmptyPrefab(prefabFullPath);
//            PrefabUtility.ReplacePrefab(batchGameObject, tempPrefab);*/
//            return batchGameObject;
//        }
//        private static GameObject GetNewGameObject(string name,ObjSource sample,Material m)
//        {
//            int partIndex = sample.part;
//            List<Vector3> listVertices = new List<Vector3>();
//            List<Vector3> listNormals = new List<Vector3>();
//            List<Vector2> listUV0 = new List<Vector2>();
//            List<Vector2> listUV2 = new List<Vector2>();
//            List<int> listIndices = new List<int>();
//            bool firstHasUv2 = false;
//            Mesh firstMesh = null;
//            int lastIndex = 0;
//
//            MeshFilter mf = sample.filter;
//            Mesh msh = mf.sharedMesh;
//
//            Vector3 tempPosition = sample.filter.transform.position;
//            Vector3 tempEulerAngles = sample.filter.transform.eulerAngles;
//            sample.filter.transform.position = Vector3.zero;
//            sample.filter.transform.eulerAngles = Vector3.zero;
//
//            Vector3 lossyScale = sample.filter.transform.lossyScale;
//            Vector3 localScale = sample.filter.transform.localScale;
//            //sample.filter.transform.localScale = new Vector3(localScale.x / lossyScale.x, localScale.y / lossyScale.y, localScale.z / lossyScale.z);
//            firstHasUv2 = msh.uv2 != null && msh.uv2.Length > 0;
//            firstMesh = msh;
//            float scale = sample.filter.transform.lossyScale.x * sample.filter.transform.lossyScale.z;
//            float faceOrder = Mathf.Clamp(scale, -1, 1);
//            foreach (Vector3 vx in msh.vertices)
//            {
//                Vector3 v = vx;
//                v = MultiplyVec3s(v, mf.gameObject.transform.lossyScale);
//                v = RotateAroundPoint(v, Vector3.zero, mf.gameObject.transform.rotation);
//                v += mf.gameObject.transform.position;
//                listVertices.Add(v);
//            }
//
//            foreach (Vector3 vx in msh.normals)
//            {
//                Vector3 v = vx;
//                v = MultiplyVec3s(v, mf.gameObject.transform.lossyScale.normalized);
//                v = RotateAroundPoint(v, Vector3.zero, mf.gameObject.transform.rotation);
//                //v.x *= -1;
//                //sb.AppendLine("vn " + v.x + " " + v.y + " " + v.z);
//                //v.x *= -1;
//                listNormals.Add(v);
//            }
//            MeshRenderer mr = sample.render;
//            foreach (Vector2 vt in msh.uv)
//            {
//                listUV0.Add(vt);
//            }
//
//            foreach (Vector2 vt in msh.uv2)
//            {
//                Vector3 vt_ = vt;
//                vt_.x = vt.x * mr.lightmapScaleOffset.x + mr.lightmapScaleOffset.z;
//                vt_.y = vt.y * mr.lightmapScaleOffset.y + mr.lightmapScaleOffset.w;
//
//                listUV2.Add(vt_);
//            }
//            for (int j = 0; j < msh.subMeshCount; j++)
//            {
//                int[] tris = msh.GetTriangles(j);
//                for (int t = 0; t < tris.Length; t += 3)
//                {
//                    int idx2 = tris[t] + lastIndex;
//                    int idx1 = tris[t + 1] + lastIndex;
//                    int idx0 = tris[t + 2] + lastIndex;
//
//                    if (faceOrder < 0)
//                    {
//                        listIndices.Add(idx0);
//                        listIndices.Add(idx1);
//                        listIndices.Add(idx2);
//                    }
//                    else
//                    {
//                        listIndices.Add(idx2);
//                        listIndices.Add(idx1);
//                        listIndices.Add(idx0);
//                    }
//                }
//            }
//            lastIndex += msh.vertices.Length;
//
//
//            Mesh mesh = new Mesh();
//            mesh.Clear();
//            mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
//            mesh.SetVertices(listVertices);
//            if (listNormals.Count > 0)
//            {
//                mesh.SetNormals(listNormals);
//            }
//
//            if (mesh.vertices.Length != listUV0.Count)
//            {
//                Debug.LogError(GetSourceName(m));
//                return new GameObject();
//            }
//            mesh.SetUVs(0, listUV0);
//            if (listUV2.Count > 0)
//            {
//                mesh.SetUVs(1, listUV2);
//            }
//            mesh.SetIndices(listIndices.ToArray(), MeshTopology.Triangles, 0);
//
//            ////write to disk
//            string prefabFullFolder = m_sceneSettings.resourcesParent + m_settings.prefabFolder;
//
//            var sourceName = GetSourceName(m);
//            string assetName = "mesh_ort_" + sourceName;
//            string prefabName = name;
//            string assetFullPath = meshPath + "/" + assetName + ".asset";
//            mesh.name = assetName;
//
//            sample.filter.transform.position = tempPosition;
//            sample.filter.transform.eulerAngles = tempEulerAngles;
//            sample.filter.transform.localScale = localScale;
//
//            AssetDatabase.CreateAsset(mesh, assetFullPath);
//
//
//
//            Material sharedMat = GetMat(mr);
//
//            GameObject batchGameObject = new GameObject(prefabName);
//
//            MeshFilter _mf = batchGameObject.AddComponent<MeshFilter>();
//            _mf.sharedMesh = mesh;//AssetDatabase.LoadAssetAtPath<Mesh>(assetFullPath);
//
//            MeshRenderer _mr = batchGameObject.AddComponent<MeshRenderer>();
//            //Debug.LogError(prefabName + " " + sharedMat);
//            _mr.sharedMaterial = sharedMat;//AssetDatabase.LoadAssetAtPath<Material>(matFullPath);
//
//            /*string prefabFullPath = prefabFullFolder + "/" + prefabName + ".prefab";
//            UnityEngine.Object tempPrefab = PrefabUtility.CreateEmptyPrefab(prefabFullPath);
//            PrefabUtility.ReplacePrefab(batchGameObject, tempPrefab);*/
//            return batchGameObject;
//        }
//        
//        private static GameObject GetNewGameObjectMultiMaterial(string name,GameObject gameObject,int partIndex)
//        {
//            List<Vector3> listVertices = new List<Vector3>();
//            List<Vector3> listNormals = new List<Vector3>();
//            List<Vector2> listUV0 = new List<Vector2>();
//            List<Vector2> listUV2 = new List<Vector2>();
//            Dictionary<int,List<int>> listIndices = new Dictionary<int,List<int>>();
//            bool firstHasUv2 = false;
//            Mesh firstMesh = null;
//            int lastIndex = 0;
//
//            MeshFilter mf = gameObject.GetComponent<MeshFilter>();
//            Mesh msh = mf.sharedMesh;
//
//            Vector3 tempPosition = gameObject.transform.position;
//            Vector3 tempEulerAngles = gameObject.transform.eulerAngles;
//            gameObject.transform.position = Vector3.zero;
//            gameObject.transform.eulerAngles = Vector3.zero;
//
//            Vector3 lossyScale = gameObject.transform.lossyScale;
//            Vector3 localScale = gameObject.transform.localScale;
//            gameObject.transform.localScale = new Vector3(localScale.x / lossyScale.x, localScale.y / lossyScale.y, localScale.z / lossyScale.z);
//            firstHasUv2 = msh.uv2 != null && msh.uv2.Length > 0;
//            firstMesh = msh;
//            float scale = gameObject.transform.lossyScale.x * gameObject.transform.lossyScale.z;
//            float faceOrder = Mathf.Clamp(scale, -1, 1);
//            foreach (Vector3 vx in msh.vertices)
//            {
//                Vector3 v = vx;
//                v = MultiplyVec3s(v, mf.gameObject.transform.lossyScale);
//                v = RotateAroundPoint(v, Vector3.zero, mf.gameObject.transform.rotation);
//                v += mf.gameObject.transform.position;
//                listVertices.Add(v);
//            }
//
//            foreach (Vector3 vx in msh.normals)
//            {
//                Vector3 v = vx;
//                v = MultiplyVec3s(v, mf.gameObject.transform.lossyScale.normalized);
//                v = RotateAroundPoint(v, Vector3.zero, mf.gameObject.transform.rotation);
//                //v.x *= -1;
//                //sb.AppendLine("vn " + v.x + " " + v.y + " " + v.z);
//                //v.x *= -1;
//                listNormals.Add(v);
//            }
//            MeshRenderer mr = gameObject.GetComponent<MeshRenderer>();
//            foreach (Vector2 vt in msh.uv)
//            {
//                listUV0.Add(vt);
//            }
//
//            foreach (Vector2 vt in msh.uv2)
//            {
//                Vector3 vt_ = vt;
//                vt_.x = vt.x * mr.lightmapScaleOffset.x + mr.lightmapScaleOffset.z;
//                vt_.y = vt.y * mr.lightmapScaleOffset.y + mr.lightmapScaleOffset.w;
//
//                listUV2.Add(vt_);
//            }
//            for (int j = 0; j < msh.subMeshCount; j++)
//            {
//                int[] tris = msh.GetTriangles(j);
//                List<int> listIndice = new List<int>();
//                listIndices.Add(j,listIndice);
//                for (int t = 0; t < tris.Length; t += 3)
//                {
//                    int idx2 = tris[t] + lastIndex;
//                    int idx1 = tris[t + 1] + lastIndex;
//                    int idx0 = tris[t + 2] + lastIndex;
//
//                    if (faceOrder < 0)
//                    {
//                        listIndice.Add(idx0);
//                        listIndice.Add(idx1);
//                        listIndice.Add(idx2);
//                    }
//                    else
//                    {
//                        listIndice.Add(idx2);
//                        listIndice.Add(idx1);
//                        listIndice.Add(idx0);
//                    }
//                }
//            }
//            lastIndex += msh.vertices.Length;
//
//
//            Mesh mesh = new Mesh();
//            mesh.Clear();
//            mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
//            mesh.SetVertices(listVertices);
//            mesh.subMeshCount = listIndices.Count;
//            if (listNormals.Count > 0)
//            {
//                mesh.SetNormals(listNormals);
//            }
//
//            if (mesh.vertices.Length != listUV0.Count)
//            {
//                //Debug.LogError(GetSourceName(m));
//                return new GameObject();
//            }
//            mesh.SetUVs(0, listUV0);
//            if (listUV2.Count > 0)
//            {
//                mesh.SetUVs(1, listUV2);
//            }
//
//            foreach (var item in listIndices)
//            {
//                mesh.SetIndices(item.Value.ToArray(), MeshTopology.Triangles, item.Key);
//            }
//
//            ////write to disk
//            string prefabFullFolder = m_sceneSettings.resourcesParent + m_settings.prefabFolder;
//
//            var sourceName = GetSourceName(gameObject) + partIndex;
//            string assetName = "mesh_ort_" + sourceName;
//            string prefabName = name;
//            string assetFullPath = meshPath + "/" + assetName + ".asset";
//            mesh.name = assetName;
//
//            gameObject.transform.position = tempPosition;
//            gameObject.transform.eulerAngles = tempEulerAngles;
//            gameObject.transform.localScale = localScale;
//
//            AssetDatabase.CreateAsset(mesh, assetFullPath);
//            
//            GameObject batchGameObject = new GameObject(prefabName);
//
//            MeshFilter _mf = batchGameObject.AddComponent<MeshFilter>();
//            _mf.sharedMesh = mesh;
//
//            MeshRenderer _mr = batchGameObject.AddComponent<MeshRenderer>();
//        
//            Material[] mats = new Material[mr.sharedMaterials.Length];
//            for (int i = 0; i < mats.Length; i++)
//            {
//                var mat = GetMat(mr.sharedMaterials[i],mr.lightmapIndex);
//                mats[i] = mat;
//            }
//            
//            _mr.sharedMaterials = mats;//AssetDatabase.LoadAssetAtPath<Material>(matFullPath);
//
//            /*string prefabFullPath = prefabFullFolder + "/" + prefabName + ".prefab";
//            UnityEngine.Object tempPrefab = PrefabUtility.CreateEmptyPrefab(prefabFullPath);
//            PrefabUtility.ReplacePrefab(batchGameObject, tempPrefab);*/
//            return batchGameObject;
//        }
//
//        private static void DeleteDir(string path, bool deleteOwner)
//        {
//            if (path.Trim() == "" || !Directory.Exists(path)) return;
//            DirectoryInfo dirInfo = new DirectoryInfo(path);
//            FileInfo[] fileInfos = dirInfo.GetFiles();
//            if (fileInfos != null && fileInfos.Length > 0)
//            {
//                foreach (FileInfo fileInfo in fileInfos)
//                {
//                    File.Delete(fileInfo.FullName);
//                }
//            }
//            DirectoryInfo[] dirInfos = dirInfo.GetDirectories();
//            if (dirInfos != null && dirInfos.Length > 0)
//            {
//                foreach (DirectoryInfo childDirInfo in dirInfos)
//                {
//                    DeleteDir(childDirInfo.FullName, true);
//                }
//            }
//            if (deleteOwner)
//            {
//                Directory.Delete(dirInfo.FullName, true);
//            }
//        }
//
//        private static void ExportBatchNode(Transform root, List<ObjSource> gameObjects, Material m,int partIndex)
//        {
//            if (gameObjects.Count <= 0) return;
//            List<Vector3> listVertices = new List<Vector3>();
//            List<Vector3> listNormals = new List<Vector3>();
//            List<Vector2> listUV0 = new List<Vector2>();
//            List<Vector2> listUV2 = new List<Vector2>();
//            List<int> listIndices = new List<int>();
//            bool firstHasUv2 = false;
//            Mesh firstMesh = null;
//            int lastIndex = 0;
//            Vector4 lightmapOffset = Vector4.zero;
//            int lightmapIndex = -1;
//            for (int i = 0; i < gameObjects.Count; i++)
//            {
//                MeshFilter mf = gameObjects[i].filter;
//                Mesh msh = mf.sharedMesh;
//                var hasUV2 = msh.uv2 != null && msh.uv2.Length > 0;
//                if (firstMesh == null && hasUV2)
//                {
//                    firstMesh = msh;
//                }
//                if (!hasUV2)
//                {
//                    continue;
//                }
//                /*if (i == 0)
//                {
//                    firstHasUv2 = msh.uv2 != null && msh.uv2.Length > 0;
//                    firstMesh = msh;
//                }
//                else*/
//                {
//                    if (firstHasUv2)
//                    {
//                        if (!(msh.uv2 != null && msh.uv2.Length > 0))
//                        {
//                            UnityEngine.Debug.LogError(firstMesh.name + ">has uv2 [" + firstMesh.uv2.Length + "] ,but <" + msh.name + "> dont has uv2: " + msh.uv2.Length);
//                        }
//                    }
//                    else
//                    {
//                        if (msh.uv2 != null && msh.uv2.Length > 0)
//                        {
//                            //UnityEngine.Debug.LogError(firstMesh.name + ">dont has uv2 [" + firstMesh.uv2.Length + "], but <" + msh.name + " >has uv2:" + msh.uv2.Length);
//                        }
//                    }
//                }
//                float scale = gameObjects[i].filter.transform.lossyScale.x * gameObjects[i].filter.transform.lossyScale.z;
//                float faceOrder = Mathf.Clamp(scale, -1, 1);
//                foreach (Vector3 vx in msh.vertices)
//                {
//                    Vector3 v = vx;
//                    v = MultiplyVec3s(v, mf.gameObject.transform.lossyScale);
//                    v = RotateAroundPoint(v, Vector3.zero, mf.gameObject.transform.rotation);
//                    v += mf.gameObject.transform.position;
//                    listVertices.Add(v);
//                }
//
//                foreach (Vector3 vx in msh.normals)
//                {
//                    Vector3 v = vx;
//                    v = MultiplyVec3s(v, mf.gameObject.transform.lossyScale.normalized);
//                    v = RotateAroundPoint(v, Vector3.zero, mf.gameObject.transform.rotation);
//                    //v.x *= -1;
//                    //sb.AppendLine("vn " + v.x + " " + v.y + " " + v.z);
//                    //v.x *= -1;
//                    listNormals.Add(v);
//                }
//                MeshRenderer mr = gameObjects[i].render;
//                if (mr.lightmapIndex != -1)
//                {
//                    lightmapIndex = mr.lightmapIndex;
//                    lightmapOffset.x = mr.lightmapScaleOffset.x;
//                    lightmapOffset.y = mr.lightmapScaleOffset.y;
//                    lightmapOffset.z = mr.lightmapScaleOffset.z;
//                    lightmapOffset.w = mr.lightmapScaleOffset.w;
//                }
//
//                foreach (Vector2 vt in msh.uv)
//                {
//                    listUV0.Add(vt);
//                }
//
//                foreach (Vector2 vt in msh.uv2)
//                {
//                    Vector3 vt_ = vt;
//                    vt_.x = vt.x * mr.lightmapScaleOffset.x + mr.lightmapScaleOffset.z;
//                    vt_.y = vt.y * mr.lightmapScaleOffset.y + mr.lightmapScaleOffset.w;
//
//                    listUV2.Add(vt_);
//                }
//                for (int j = 0; j < msh.subMeshCount; j++)
//                {
//                    int[] tris = msh.GetTriangles(j);
//                    for (int t = 0; t < tris.Length; t += 3)
//                    {
//                        int idx2 = tris[t] + lastIndex;
//                        int idx1 = tris[t + 1] + lastIndex;
//                        int idx0 = tris[t + 2] + lastIndex;
//
//                        if (faceOrder < 0)
//                        {
//                            listIndices.Add(idx0);
//                            listIndices.Add(idx1);
//                            listIndices.Add(idx2);
//                        }
//                        else
//                        {
//                            listIndices.Add(idx2);
//                            listIndices.Add(idx1);
//                            listIndices.Add(idx0);
//                        }
//                    }
//                }
//                lastIndex += msh.vertices.Length;
//
//            }
//
//            Mesh mesh = new Mesh();
//            mesh.Clear();
//            mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
//            mesh.SetVertices(listVertices);
//            if (listNormals.Count > 0)
//            {
//                mesh.SetNormals(listNormals);
//            }
//
//            if (mesh.vertices.Length != listUV0.Count)
//            {
//                Debug.LogError(GetSourceName(m));
//                return;
//            }
//            mesh.SetUVs(0, listUV0);
//            if (listUV2.Count > 0)
//            {
//                mesh.SetUVs(1, listUV2);
//            }
//            mesh.SetIndices(listIndices.ToArray(), MeshTopology.Triangles, 0);
//
//            ////write to disk
//            string prefabFullFolder = m_sceneSettings.resourcesParent + m_settings.prefabFolder;
//
//            var sourceName = GetSourceName(m) + "0" + partIndex;
//            string assetName = "mesh_btc_" + sourceName;
//            string prefabName = "prf_btc_" + sourceName;
//            string assetFullPath = meshPath + "/" + assetName + ".asset";
//            mesh.name = assetName;
//            AssetDatabase.CreateAsset(mesh, assetFullPath);
//
//            /*string matFullPath = prefabFullFolder + "/" + matName + ".mat";
//            Material cloneMat = UnityEngine.Object.Instantiate(m);
//            cloneMat.name = matName;
//            cloneMat.shader = shader;
//            cloneMat.renderQueue = m.renderQueue;
//
//            cloneMat.enableInstancing = false;
//            AssetDatabase.CreateAsset(cloneMat, matFullPath);*/
//
//            AssetDatabase.Refresh();
//            GameObject batchGameObject = new GameObject(prefabName);
//
//            MeshFilter _mf = batchGameObject.AddComponent<MeshFilter>();
//            _mf.sharedMesh = AssetDatabase.LoadAssetAtPath<Mesh>(assetFullPath);
//
//            MeshRenderer _mr = batchGameObject.AddComponent<MeshRenderer>();
//            _mr.sharedMaterial = m;//AssetDatabase.LoadAssetAtPath<Material>(matFullPath);
//
//            batchGameObject.transform.parent = root;
//
//            string prefabFullPath = prefabRootPath + "/" + prefabName + ".prefab";
//            UnityEngine.Object tempPrefab = PrefabUtility.CreateEmptyPrefab(prefabFullPath);
//            PrefabUtility.ReplacePrefab(batchGameObject, tempPrefab);
//
//            var child = batchGameObject.transform;
//            var obj = new SSceneConfig.SceneObj();
//            obj.lightmapIndex = lightmapIndex;
//            obj.lightmapScaleOffset = lightmapOffset;
//
//
//            if (m.HasProperty("_Quality"))
//            {
//                obj.quality = m.GetInt("_Quality");
//            }
//            obj.position = child.position;
//            obj.scale = child.lossyScale;
//            obj.rotation = child.rotation.eulerAngles;
//            // obj.positiony = child.localPosition.y;
//            // obj.positionz = child.localPosition.z;
//            //
//            // obj.rotationx = child.transform.localEulerAngles.x;
//            // obj.rotationy = child.transform.localEulerAngles.y;
//            // obj.rotationz = child.transform.localEulerAngles.z;
//            //
//            // obj.scalex = child.transform.localScale.x;
//            // obj.scaley = child.transform.localScale.y;
//            // obj.scalez = child.transform.localScale.z;
//
//            obj.name = prefabName;
//            obj.path = prefabFullPath;
//            obj.part = partIndex;
//            obj.partOffset = partOffsetList[obj.part];
//            m_settings.objs.Add(obj);
//            batchGameObject.transform.SetParent(null);
//            GameObject.DestroyImmediate(batchGameObject);
//            Debug.Log("合批了材质名字为: " + m.name + "的对象共:" + gameObjects.Count);
//        }
//        private static Vector3 MultiplyVec3s(Vector3 v1, Vector3 v2)
//        {
//            return new Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
//        }
//        private static Vector3 RotateAroundPoint(Vector3 point, Vector3 pivot, Quaternion angle)
//        {
//            return angle * (point - pivot) + pivot;
//        }
//        private static string ConstructOBJString(int index)
//        {
//            string idxString = index.ToString();
//            return idxString + "/" + idxString + "/" + idxString;
//        }
//        private static void FilterRoot(Transform root, ref List<MeshRenderer> list,int partIndex)
//        {
//            for (int i = 0; i < root.childCount; i++)
//            {
//                var a = root.transform.GetChild(i);
//                if (a.name.Contains("eff")) continue;
//                MeshRenderer[] m = a.GetComponentsInChildren<MeshRenderer>();
//                for (int j = 0; j < m.Length; j++)
//                {
//                    if (list.Contains(m[j])) continue;
//                    if (!m[j].gameObject.activeInHierarchy) continue;
//                    if (m[j].shadowCastingMode != ShadowCastingMode.On) continue;
//
//                    var filter = m[j].gameObject.GetComponent<MeshFilter>();
//                    if (filter == null)
//                    {
//                        Debug.LogError(m[j].gameObject + " dont has meshFilter");
//                        continue;
//                    }
//
//                    var mesh = filter.sharedMesh;
//                    if (mesh == null)
//                    {
//                        Debug.LogError(m[j].gameObject + " dont has sharedMesh");
//                        continue;
//                    }
//                    int meshInstanceId = mesh.GetInstanceID();
//                    if (m[j].sharedMaterial == null)
//                    {
//                        continue;
//                    }
//
//                    if (m[j].sharedMaterials != null && m[j].sharedMaterials.Length > 1)
//                    {
//                        multiMaterialPrefabs.Add(new MultiMaterialGameObject
//                        {
//                            gameObject = m[j].gameObject,
//                            part = partIndex,
//                        });
//                        for (int k = 0; k < m[j].sharedMaterials.Length; k++)
//                        {
//                            GetMultiMat(m[j], m[j].sharedMaterials[k].shader, m[j].sharedMaterials[k]);
//                        }
//                        continue;
//                    }
//
//                    var shader = m[j].sharedMaterial.shader;
//                    var mat = GetMat(m[j], shader);
//                    int matInstanceId = mat.GetInstanceID();
//                    bool addNewPrefab = true;
//                    if (prefabs.TryGetValue(meshInstanceId, out var prefab))
//                    {
//                        if (prefab.TryGetValue(matInstanceId, out var realPrefab))
//                        {
//                            addNewPrefab = false;
//                            realPrefab.objsDic[m[j].gameObject.GetHashCode()] = m[j].gameObject;
//                        }
//                        else
//                        {
//                            var prefabInstance = new PrefabInstance
//                            {
//                                name = m[j].name,
//                                sourceObj = m[j].gameObject,
//
//                            };
//                            prefabInstance.objsDic[m[j].gameObject.GetHashCode()] = m[j].gameObject;
//                            prefab.Add(matInstanceId, prefabInstance);
//
//                        }
//                    }
//                    else
//                    {
//                        prefabs.Add(meshInstanceId, new Dictionary<int, PrefabInstance>
//                        {
//                            [matInstanceId] = new PrefabInstance
//                            {
//                                name = m[j].name,
//                                sourceObj = m[j].gameObject,
//                                objsDic = new Dictionary<int, GameObject>
//                                {
//                                    [m[j].gameObject.GetHashCode()] = m[j].gameObject,
//                                },
//                            },
//                        });
//                    }
//                    list.Add(m[j]);
//                }
//            }
//        }
//
//        private class PrefabInstance
//        {
//            public string name;
//            public GameObject sourceObj;
//            public Dictionary<int,GameObject> objsDic = new Dictionary<int, GameObject>();
//        }
//
//        private class MultiMaterialGameObject
//        {
//            public GameObject gameObject;
//            public int part;
//        }
//        
//        private static Dictionary<int,Dictionary<int,PrefabInstance>> prefabs = new Dictionary<int,Dictionary<int,PrefabInstance>>();
//
//        private static HashSet<MultiMaterialGameObject> multiMaterialPrefabs =  new HashSet<MultiMaterialGameObject>();
//
//        private static void GetParentNames(Transform root, ref List<string> list)
//        {
//            if (root.parent != null)
//            {
//                list.Insert(0, root.parent.name);
//                GetParentNames(root.parent, ref list);
//            }
//        }
//
//        private static void CheckMaterial(GameObject root)
//        {
//            var renderer = root.GetComponentsInChildren<Renderer>(true);
//            List<Material> mats = new List<Material>();
//            foreach (var re in renderer)
//            {
//                var smats = re.sharedMaterials;
//                foreach (var mat in smats)
//                {
//                    if (!mats.Contains(mat))
//                        mats.Add(mat);
//                }
//            }
//
//            List<Texture> textures = new List<Texture>();
//
//            int handleIndex = 0;
//            foreach (var mat in mats)
//            {
//                handleIndex++;
//                if (mat == null)
//                    continue;
//
//                EditorUtility.DisplayProgressBar("材质清理中", string.Format("{0}/{1}: {2}", handleIndex, mats.Count, mat.name), handleIndex / (float)mats.Count);
//
//                string filePath = AssetDatabase.GetAssetPath(mat);
//                if (string.IsNullOrEmpty(filePath))
//                {
//                    Debug.LogError(string.Format(" 使用Unity内置 material: {0}", mat.name), mat);
//                    continue;
//                }
//
//                SerializedObject matInfo = new SerializedObject(mat);
//                SerializedProperty propArr = matInfo.FindProperty("m_SavedProperties");
//                propArr = matInfo.FindProperty("m_SavedProperties");
//                SerializedProperty texEnvs = propArr.FindPropertyRelative("m_TexEnvs");
//                for (int j = texEnvs.arraySize - 1; j >= 0; j--)
//                {
//                    var idx = texEnvs.GetArrayElementAtIndex(j);
//                    string propertyName = idx.displayName;
//                    Texture tex = mat.GetTexture(propertyName);
//                    if (tex == null)
//                    {
//                        //Debug.LogError(string.Format("{0} :empty texture: {1}", mat.name, propertyName), mat);
//                        continue;
//                    }
//
//                    if (!textures.Contains(tex))
//                        textures.Add(tex);
//                }
//            }
//
//
//            List<string> texPath = new List<string>();
//            handleIndex = 0;
//            foreach (var source in textures)
//            {
//                handleIndex++;
//                EditorUtility.DisplayProgressBar("贴图检查中", string.Format("{0}/{1}: {2}", handleIndex, textures.Count, source.name), handleIndex / (float)textures.Count);
//
//                string filePath = AssetDatabase.GetAssetPath(source);
//                TextureImporter import = AssetImporter.GetAtPath(filePath) as TextureImporter;
//                if (import == null)
//                {
//                    Debug.LogError(string.Format(" 使用Unity内置 texture: {0}", source.name), source);
//                    continue;
//                }
//
//
//                texPath.Add(filePath);
//            }
//
//
//
//            AssetDatabase.SaveAssets();
//
//            EditorUtility.ClearProgressBar();
//        }
//
//        private static void AsynclizeSinglePart(Transform root,int partIndex)
//        {
//            List<MeshRenderer> meshRenderers = new List<MeshRenderer>();
//            FilterRoot(root, ref meshRenderers,partIndex);
//            Dictionary<int, ObjSource> batchedDic = new Dictionary<int, ObjSource>();
//            List<MeshRenderer> usedMeshRenders = new List<MeshRenderer>();
//            for (int i = 0; i < meshRenderers.Count; i++)
//            {
//                var mr = meshRenderers[i];
//                if (!mr.gameObject.activeInHierarchy)
//                {
//                    continue;
//                }
//                Material mat = mr.sharedMaterial;
//                if (mat == null)
//                {
//                    UnityEngine.Debug.LogError("mat is null:" + mr.name);
//                    meshRenderers.RemoveAt(i);
//                    --i;
//                    continue;
//                }
//                MeshFilter filter = mr.GetComponent<MeshFilter>();
//                if (filter == null || filter.sharedMesh == null)
//                {
//                    UnityEngine.Debug.LogError("MeshFilter is null:" + mr.name);
//                    meshRenderers.RemoveAt(i);
//                    --i;
//                    continue;
//                }
//
//                mat = GetMat(mr);
//                usedMeshRenders.Add(mr);
//                Dictionary<int, List<ObjSource>> goList = null;
//                if (m_batchedGameObjectDict.TryGetValue(mat, out goList) == false)
//                {
//                    goList = new Dictionary<int, List<ObjSource>>();
//                    m_batchedGameObjectDict.Add(mat, goList);
//                }
//                List<ObjSource> l = null;
//                if (goList.TryGetValue(filter.sharedMesh.GetInstanceID(), out l) == false)
//                {
//                    var gL = new List<ObjSource>();
//                    string status = "";
//                    Color statusColor = Color.white;
//                    var trianglesCount = filter.sharedMesh.triangles.Length / 3;
//                    if (trianglesCount > 200 && trianglesCount < m_sceneSettings.needInstVertexCount)
//                    {
//                        status = "Warning   考虑减少面数 200以下";
//                        statusColor = Color.yellow;
//                    }
//                    else if (trianglesCount > m_sceneSettings.needInstVertexCount)
//                    {
//                        status = "Error   减少面数 " + m_sceneSettings.needInstVertexCount + "以下";
//                        statusColor = Color.red;
//                    }
//                    gL.Add(new ObjSource()
//                    {
//                        layer = mr.gameObject.layer,
//                        filter = filter,
//                        render = mr,
//                        vertexCount = filter.sharedMesh.vertexCount,
//                        trianglesCount = trianglesCount,
//                        matName = mat.name,
//                        objName = mr.name + "s"+ partIndex,
//                        status = status,
//                        statusColor = statusColor,
//                        part = partIndex,
//                    });
//                    goList.Add(filter.sharedMesh.GetInstanceID(), gL);
//                }
//                else
//                {
//                    l.Add(new ObjSource()
//                    {
//                        layer = mr.gameObject.layer,
//                        filter = filter,
//                        render = mr,
//                        vertexCount = filter.sharedMesh.vertexCount,
//                        trianglesCount = filter.sharedMesh.triangles.Length / 3,
//                        matName = mat.name,
//                        objName = mr.name + "s"+ partIndex,
//                        part = partIndex,
//                    });
//                }
//            }
//
//            Dictionary<Material, List<int>> dele = new Dictionary<Material, List<int>>();
//            foreach (var item in m_batchedGameObjectDict)
//            {
//                foreach (var m in item.Value)
//                {
//                    if (m.Value.Count >= m_sceneSettings.needInstCount && m.Value[0].filter.sharedMesh.vertexCount > m_sceneSettings.needInstVertexCount && m_sceneSettings.outputType == 0)
//                    {
//                        List<int> l;
//                        if (dele.TryGetValue(item.Key, out l))
//                        {
//                            l.Add(m.Key);
//                        }
//                        else
//                        {
//                            l = new List<int>();
//                            l.Add(m.Key);
//                            dele.Add(item.Key, l);
//                        }
//                    }
//                }
//            }
//            foreach (var item in dele)
//            {
//                for (int i = 0; i < item.Value.Count; i++)
//                {
//                    var l = m_batchedGameObjectDict[item.Key];
//                    for (int j = 0; j < l[item.Value[i]].Count; j++)
//                    {
//                        usedMeshRenders.Remove(l[item.Value[i]][j].render);
//                    }
//                    l.Remove(item.Value[i]);
//                    if (l.Count <= 0)
//                    {
//                        m_batchedGameObjectDict.Remove(item.Key);
//                    }
//                }
//            }
//
//            foreach (KeyValuePair<Material, Dictionary<int, List<ObjSource>>> entry in m_batchedGameObjectDict)
//            {
//                var mat = entry.Key;
//                var goList = entry.Value;
//
//                if (goList.Count > 0)
//                {
//                    List<ObjSource> list = new List<ObjSource>();
//                    foreach (var item in goList)
//                    {
//                        list.AddRange(item.Value);
//                    }
//                    foreach (var go in list)
//                    {
//                        batchedDic.Add(go.filter.gameObject.GetInstanceID(), go);
//                    }
//                }
//            }
//            Dictionary<int, List<ObjSource>> dic = new Dictionary<int, List<ObjSource>>();
//            for (int i = 0; i < meshRenderers.Count; i++)
//            {
//                var mr = meshRenderers[i];
//                var position = mr.transform.position;
//                var angle = mr.transform.eulerAngles;
//                var scale = mr.transform.lossyScale;
//                var mat = mr.sharedMaterial;
//                if (usedMeshRenders.Contains(mr)) continue;
//                var sourceObj = PrefabUtility.GetPrefabParent(mr.gameObject);
//                if (sourceObj == null)
//                {
//                    int meshId = mr.gameObject.GetComponent<MeshFilter>().sharedMesh.GetInstanceID();
//                    int matId = mr.sharedMaterial.GetInstanceID();
//                    if (prefabs.TryGetValue(meshId, out var prefab))
//                    {
//                        if (prefab.TryGetValue(matId, out var p))
//                        {
//                            if (p.objsDic.TryGetValue(mr.gameObject.GetHashCode(), out GameObject obj))
//                            {
//                                sourceObj = obj;
//                                mr = p.sourceObj.GetComponent<MeshRenderer>();
//                            }
//                        }
//                    }
//                }
//
//                if (sourceObj == null)
//                {
//                    Debug.LogError(mr.gameObject.name + "没有prefab");
//                    continue;
//                }
//                int ins = sourceObj.GetInstanceID();
//                var filter = mr.GetComponent<MeshFilter>();
//                int index = m_sceneSettings.toGpuInstancingShaderNames.IndexOf(mat.shader.name);
//                if (index < 0) continue;
//                usedMeshRenders.Add(mr);
//                List<ObjSource> mrs;
//                if (dic.TryGetValue(ins, out mrs))
//                {
//                    mrs.Add(new ObjSource()
//                    {
//                        layer = mr.gameObject.layer,
//                        filter = filter,
//                        render = mr,
//                        vertexCount = filter.sharedMesh.vertexCount,
//                        trianglesCount = filter.sharedMesh.triangles.Length / 3,
//                        matName = mr.sharedMaterial.name,
//                        objName = mr.name + "s"+ partIndex,
//                        part = partIndex,
//                        position = position,
//                        scale = scale,
//                        angle = angle,
//                    });
//                }
//                else
//                {
//                    mrs = new List<ObjSource>();
//                    mrs.Add(new ObjSource()
//                    {
//                        layer = mr.gameObject.layer,
//                        filter = filter,
//                        render = mr,
//                        vertexCount = filter.sharedMesh.vertexCount,
//                        trianglesCount = filter.sharedMesh.triangles.Length / 3,
//                        matName = mr.sharedMaterial.name,
//                        objName = mr.name + "s"+ partIndex,
//                        part = partIndex,
//                        position = position,
//                        scale = scale,
//                        angle = angle,
//                    });
//                    dic.Add(ins, mrs);
//                }
//            }
//            foreach (var item in dic)
//            {
//                Dictionary<int, List<ObjSource>> l;
//                if (m_gpuinstancingGameObjectDic.TryGetValue(item.Value[0].render.sharedMaterial, out l))
//                {
//                    var ins = item.Value[0].filter.sharedMesh.GetInstanceID();
//                    List<ObjSource> ls;
//                    if (l.TryGetValue(ins, out ls))
//                    {
//                        //UnityEngine.Debug.Log("unkonwn");
//                    }
//                    else
//                    {
//                        l.Add(ins, item.Value);
//                    }
//                }
//                else
//                {
//                    l = new Dictionary<int, List<ObjSource>>();
//                    var ins = item.Value[0].filter.sharedMesh.GetInstanceID();
//                    l.Add(ins, item.Value);
//                    m_gpuinstancingGameObjectDic.Add(item.Value[0].render.sharedMaterial, l);
//                }
//                foreach (var it in l)
//                {
//                    string status = "";
//                    Color color = Color.white;
//                    if (it.Value.Count == 3)
//                    {
//                        status = "Warning   考虑减少面数，" + m_sceneSettings.needInstVertexCount + "以下";
//                        color = Color.yellow;
//                    }
//                    else if (it.Value.Count < 3)
//                    {
//                        status = "Error   重复太少,不要使用此shader";
//                        color = Color.red;
//                    }
//                    for (int i = 0; i < it.Value.Count; i++)
//                    {
//                        it.Value[i].status = status;
//                        it.Value[i].statusColor = color;
//                    }
//                }
//            }
//
//            if (m_sceneSettings.outputType == 1)
//            {
//                m_batchedGameObjectDict.Clear();
//                m_gpuinstancingGameObjectDic.Clear();
//                usedMeshRenders.Clear();
//            }
//
//            for (int i = 0; i < meshRenderers.Count; i++)
//            {
//                var mr = meshRenderers[i];
//                var mat = mr.sharedMaterial;
//                if (!mr.gameObject.activeInHierarchy)
//                {
//                    continue;
//                }
//                if (usedMeshRenders.Contains(mr)) continue;
//                mat = GetMat(mr);
//                var position = mr.transform.position;
//                var angle = mr.transform.eulerAngles;
//                var scale = mr.transform.lossyScale;
//                List<ObjSource> l;
//                int meshId = mr.gameObject.GetComponent<MeshFilter>().sharedMesh.GetInstanceID();
//                int matId = mr.sharedMaterial.GetInstanceID();
//                if (prefabs.TryGetValue(meshId, out var prefab))
//                {
//                    if (prefab.TryGetValue(matId, out var p))
//                    {
//                        mr = p.sourceObj.GetComponent<MeshRenderer>();
//                    }
//                }
//                if (m_otherGameObjectDic.TryGetValue(mat, out l))
//                {
//                    var filter = mr.GetComponent<MeshFilter>();
//                    int trianglesCount = filter.sharedMesh.triangles.Length / 3;
//                    string status = "";
//                    Color color = Color.white;
//                    if (trianglesCount > 200 && trianglesCount < m_sceneSettings.needInstVertexCount)
//                    {
//                        status = "Warning   考虑减少面数，200以下";
//                        color = Color.yellow;
//                    }
//                    else if (trianglesCount > m_sceneSettings.needInstVertexCount)
//                    {
//                        status = "Error  减少面数，" + m_sceneSettings.needInstVertexCount + "以下";
//                        color = Color.red;
//                    }
//                    l.Add(new ObjSource()
//                    {
//                        layer = mr.gameObject.layer,
//                        filter = filter,
//                        render = mr,
//                        vertexCount = filter.sharedMesh.vertexCount,
//                        trianglesCount = trianglesCount,
//                        matName = mat.name,
//                        objName = mr.name + "s"+ partIndex,
//                        status = status,
//                        statusColor = color,
//                        part = partIndex,
//                        position = position,
//                        scale = scale,
//                        angle = angle,
//                    });
//                }
//                else
//                {
//                    l = new List<ObjSource>();
//                    var filter = mr.GetComponent<MeshFilter>();
//                    int trianglesCount = filter.sharedMesh.triangles.Length / 3;
//                    string status = "";
//                    Color color = Color.white;
//                    if (trianglesCount > 200 && trianglesCount < m_sceneSettings.needInstVertexCount)
//                    {
//                        status = "Warning   考虑减少面数，200以下";
//                        color = Color.yellow;
//                    }
//                    else if (trianglesCount > m_sceneSettings.needInstVertexCount)
//                    {
//                        status = "Error  减少面数，" + m_sceneSettings.needInstVertexCount + "以下";
//                        color = Color.red;
//                    }
//                    l.Add(new ObjSource()
//                    {
//                        layer = mr.gameObject.layer,
//                        filter = filter,
//                        render = mr,
//                        vertexCount = filter.sharedMesh.vertexCount,
//                        trianglesCount = trianglesCount,
//                        matName = mat.name,
//                        objName = mr.name + "s" + partIndex,
//                        status = status,
//                        statusColor = color,
//                        part = partIndex,
//                        position = position,
//                        scale = scale,
//                        angle = angle,
//                    });
//                    m_otherGameObjectDic.Add(mat, l);
//                }
//            }
//        }
//
//        private static GameObject skyBoxObj;
//
//        private static void Asynclize(Transform root)
//        {
//            m_exportedStrList.Clear();
//            m_batchedGameObjectDict.Clear();
//            m_gpuinstancingGameObjectDic.Clear();
//            m_otherGameObjectDic.Clear();
//            int index = 0;
//            for (int i = 0; i < root.childCount; i++)
//            {
//                var child = root.GetChild(i);
//                if (child.gameObject.name == "skybox")
//                {
//                    skyBoxObj = child.gameObject;
//                }
//                else
//                {
//                    AsynclizeSinglePart(child,index);
//                    index++;
//                }
//            }
//
//        }
//        private void PingObject(UnityEngine.Object obj)
//        {
//            EditorGUIUtility.PingObject(obj);
//            Selection.activeObject = obj;
//        }
//        private static void LogToString(string str)
//        {
//            m_logString.Add(str);
//        }
//        private static void InitConfig(string subRootName)
//        {
//            //if (m_settings == null)
//            {
//
//            }
//        }
//        private static string GetSourceName(UnityEngine.Object obj)
//        {
//            string sourceFile = "";
//            if (obj is GameObject)
//            {
//                var source = PrefabUtility.GetPrefabParent(obj);
//                if (source == null) return obj.name;
//                sourceFile = AssetDatabase.GetAssetPath(source);
//            }
//            else
//            {
//                sourceFile = AssetDatabase.GetAssetPath(obj);
//            }
//            FileInfo info = new FileInfo(sourceFile);
//            var sourceName = info.Name.Substring(0, info.Name.IndexOf('.'));
//            Dictionary<string, int> list = null;
//            LogToString("GetSourceName:" + obj.GetType() + "   " + sourceName);
//            if (m_exportedStrList.TryGetValue(obj.GetType(), out list))
//            {
//                if (list.ContainsKey(sourceName))
//                {
//                    list[sourceName]++;
//                }
//                else
//                {
//                    list.Add(sourceName, 0);
//                }
//            }
//            else
//            {
//                list = new Dictionary<string, int>();
//                list.Add(sourceName, 0);
//                m_exportedStrList.Add(obj.GetType(), list);
//            }
//            var name = list[sourceName]>0?sourceName + "_" + list[sourceName]:sourceName;
//            name = name.Replace('(', 's');
//            name = name.Replace(')', 'k');
//            name = name.Replace('[', 'p');
//            name = name.Replace(']', 'u');
//            name = name.Replace('#', '_');;
//            return name;
//        }
//    }
//}
